<?php

    global $mikron;
    $mikron_votings = new MikronVotings();

    $mikron->OperatingInstructions->AddFunction('VOTING', 'VotingOperatingInstruction', $mikron_votings);
    $mikron->OperatingInstructions->AddFunction('VOTING_RESULTS', 'ShowVotingResults', $mikron_votings);
    $mikron->OperatingInstructions->AddFunction('VOTING_EDITOR', 'ShowVotingEditor', $mikron_votings);

    $mikron->Schema->Add(dirname(__FILE__).'/schema.xml', 'Схема голосований');

    $mikron->Handlers->AddSaveHandler('createVotingFast', Array('VOTING_NEW'), $mikron_votings);

    class MikronVotings
    {
        public function ShowVotingEditor($parameters)
        {
            global $mikron;
            ?>
            {{slidewindow caption="Форма создания голосования" showtext=Создать hidetext=Отмена}}
            {{userform entityname=VOTING_NEW cellspacing=0 cellpadding=2 submit_caption=Создать}}
            {{/slidewindow}}<br />
            <h1>Все опросы:</h1>
            <?php
            /**
            * Вывод всех голосований в виде кода, готового к вставке на страницу
            * 
            * @var QueryClass
            */
            $votings = $mikron->Queries->Query('VOTING', null, null, '`id` ASC');
            while($voting = $votings->fetch())
            {
                $code = $voting->title->value;
                $question = $voting->question->value;
                echo sprintf('<code>{<span>{VOTING code="%s"}</span>}</code> <span style="color: #0a0; font-size: .9em; "><<span>!-- %s --</span>></span>', $code, $question).'<br />';
            }
        }

        public function createVotingFast(VOTING_NEW &$entity)
        {
            global $mikron;
            $mikron->Queries->StartTransaction();
            try
            {
                $this->createVotingFast_Function($entity);
                $mikron->Queries->CommitTransaction();
            }
            catch(Exception $ex)
            {
                $mikron->Queries->RollbackTransaction();                
            }
        }

        private function createVotingFast_Function(VOTING_NEW $entity)
        {
            global $mikron;
            if($entity instanceof VOTING_NEW)
            {
                $code = $entity->code->value;
                $question = $entity->question->value;
                $choicesArray = explode("\r\n", trim($entity->choices->value));
                $choicesArray = array_reverse($choicesArray);
                $choicetype = $entity->choicetype->value;
                $voting = new VOTING(null);
                $voting->title->value = $code;
                $voting->question->value = $question;
                $voting->choicetype->value = $choicetype;
                $voting->Save();
                $choices = Array();
                foreach($choicesArray as $answer)
                {
                    $answer = trim($answer);
                    if(strlen($answer))
                    {
                        $custom = explode('?', $answer, 2);
                        $choice = new VOTING_CHOICE();
                        $choice->voting->value = $voting->id;
                        $choice->answer->value = $custom[0];
                        $choice->custom->value = count($custom) == 2;
                        $choice->Save();
                    }
                }
            }
            /**
            * Чтобы микрон не сохранял объект, т.к. мы уже все что нужно было сделали с объектом
            */
            return false;
        }

        public function ShowVotingResults($parameters)
        {
            global $mikron;
            $code = $parameters['code'];
            $votings = $mikron->Queries->Query('VOTING', null, new Criterion('title', $code));
            if($votings->count() < 1)
            {
                echo "<font color=\"red\">Голосование «$code» не существует.</font>";
                return;
            }
            $voting = $votings->fetch();
            $cr = new Criteria();
            $cr->add(new Criterion('voting', $voting->id));
            $results = $mikron->Queries->Query('VOTING_RESULT', null, $cr);
            $res = Array();
            $all_count = 0;
            while($vr = $results->fetch())
            {
                $choice = $vr->choice->value;
                $answer = $choice->answer->value;
                $all_count++;
                if(array_key_exists($answer, $res))
                {
                    $res[$answer]++;
                }
                else
                {
                    $res[$answer] = 1;
                }
            }
            $question = htmlspecialchars($voting->question->value);
            echo sprintf('<h1 style="margin: 0px;>%s</h1>', $question);
            $table = new html_table(2, null, null, 0);
            while($choice = $voting->choices->value->fetch())
            {
                $count = 0;
                if(array_key_exists($choice->answer->value, $res))
                {
                    $count = $res[$choice->answer->value];
                }
                $table->newcol($choice->answer->value, true);
                $percent = 0;
                if($all_count)
                {
                    $percent = $count / $all_count;
                }
                $table->newcol('&nbsp;<font color="888888">'.round($percent * 100, 1).'% ('.$count.'шт)</font>');
            }
            $table->end();
        }

        private function ProcessVoting(&$voting, $form_data)
        {
            global $mikron;
            $code = $voting->title->value;
            $customValues = $mikron->Tools->GetParam($form_data, 'mikron_custom_value', null);
            if(!is_array($customValues))
            {
                $customValues = Array();
            }
            $value = (int)$form_data['choice'];
            $ok = false;
            while($choice = $voting->choices->value->fetch())
            {
                if($choice->id == $value)
                {
                    try
                    {
                        $votings = $mikron->Cache->getCache('votings');
                        if(is_array($votings))
                        {
                            $votings[] = $code;
                        }
                        else
                        {
                            $votings = Array($code);
                        }
                        $mikron->Cache->setCache('votings', $votings);
                        $voting_result = new VOTING_RESULT();
                        $voting_result->voting->value = $voting->id;
                        $voting_result->choice->value = $choice->id;
                        $customValue = $mikron->Tools->GetParam($customValues, $choice->id, null);
                        $voting_result->custom->value = $customValue;
                        if(!is_null($mikron->Users->Currentuser()->user))
                        {
                            $voting_result->user->value = $mikron->Users->Currentuser()->id();
                        }
                        $voting_result->Save();
                        echo '<font color="green">Спасибо, Ваш голос учтен.</font>';
                        $ok = true;
                        break;
                    }
                    catch(Exception $ex)
                    {
                        throw new MikronException('<span class="error_font">Ошибка сервера при голосовании.</span>');
                    }
                }
            }
        }

        public function VotingOperatingInstruction($parameters)
        {
            global $mikron;
            $code = $parameters['code'];

            $voting = $mikron->Queries->QueryOne('VOTING', null, new Criterion('title', $code));
            if(is_null($voting))
            {
                echo "<font color=\"red\">Голосование «$code» не существует.</font>";
                return;
            }

            $uri = $_SERVER['REQUEST_URI'].'#voting'.$voting->id;

            if(is_null($mikron->Users->Currentuser()->user))
            {
                $votings = $mikron->Cache->getCache('votings');
                if(is_array($votings))
                {
                    if(in_array($code, $votings))
                    {
                        // Mikron_ShowVotingResults($parameters);
                        return;
                    }
                }
            }
            else
            {
                $cr = new Criteria();
                $cr->add(new Criterion('voting', $voting->id));
                $cr->add(new Criterion('user', $mikron->Users->Currentuser()->id()));
                $results = $mikron->Queries->Query('VOTING_RESULT', null, $cr);
                if($results->count() > 0)
                {
                    // Mikron_ShowVotingResults($parameters);
                    return;
                }
            }

            $form = new html_form('voting'.$code, 'post', $uri, null);
            $isCancelDisplayVoting = false;
            $errorDescription = null;
            try
            {
                if($form->pageindex == 2)
                {
                    // Обработка голоса
                    $this->ProcessVoting($voting, $form->formdata);
                }
                else
                {
                    $this->DisplayVoting($voting, $form);
                }
            }
            catch(Exception $ex)
            {
                $isCancelDisplayVoting = true;
                $errorDescription = $ex->getMessage();
            }
            $form->end($isCancelDisplayVoting);
            if($isCancelDisplayVoting)
            {
                echo sprintf($errorDescription);
            }
        }

        /**
        * Отрисовка
        */
        private function DisplayVoting(VOTING $voting, html_form &$form)
        {
            global $mikron;
            $choice_type = $voting->choicetype->value;
            $votingQuestion = htmlspecialchars($voting->question->value);
            $votingId = $voting->id;
            echo sprintf('<h3 style="margin: 0px; ">%s</h3><a name="%s"></a>', $votingQuestion, 'voting'.$votingId);
            $table = new html_table(1);
            $choices_count = $voting->choices->value->count();
            while($choice = $voting->choices->value->fetch())
            {
                $table->newcol();
                $custom_require = $choice->custom->value == 1;
                $customId = null;
                if($custom_require)
                {
                    $customId = 'custom'.md5(time().mt_rand(0, 99999999).$choice->id.$votingId);
                }
                if($choice_type == 1) // radio
                {
                    $form->addRadio(1, 'choice', $choice->answer->value, null, $choice->id, null, $choices_count == 1);
                }
                elseif($choice_type == 2) // checkbox
                {
                    $form->addCheckbox(1, 'checkboxes', $choice->answer->value, null, $choices_count == 1); 
                }
                if($custom_require)
                {
                    if(!$mikron->Tools->IsNullOrEmpty($choice->answer->value))
                    {
                        echo '&nbsp;';
                    }
                    $form->addInput(1, 'mikron_custom_value', null, null, null, false, null, false, 'text', $customId, $choice->id);
                }
            }
            $table->newcol();
                $form->addSubmit('votingop', 'Ok');
            $table->end();            
        }

    }

?>